<!doctype html>
<html lang="en">
<head><meta name="generator" content="Hexo 3.9.0">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>言成言成啊</title>
    <link rel="shortcut icon" href="/images/favicon.ico">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/meethigher/cdn@9.0/css/meethigher-font.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/meethigher/cdn@9.0/css/animate.css">
    <link rel="stylesheet" href="/css/index.css">
</head>
<body>
<header class="header">
    <div class="header-menu"><span class="fa fa-bars"></span></div>
    <div class="header-search"><span class="fa fa-search"></span></div>
    <div class="header-title"><a href="/">言成言成啊 | <span class="header-subtitle">Kit Chen&#39;s Blog</span></a></div>
    <ul class="header-navbar clearFix">
        
            <li><a href="/">主页</a></li>
        
            <li><a href="/tags">标签</a></li>
        
            <li><a href="/archives">归档</a></li>
        
            <li><a href="/search">导航</a></li>
        
    </ul>
</header>
<main class="main">
    <div class="main-content meethigher-scroll">
    <article class="post">
        <div class="post-title">
            <h2 class="title">浅谈多态</h2>
        </div>
        <div class="post-media2">
            <span class="post-time">2019-09-23</span>
            
                <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/java/">java</a></li></ul>
            
        </div>
        <div class="post-content blog-markdown">
            <h2 id="一、多态的概述以及使用"><a href="#一、多态的概述以及使用" class="headerlink" title="一、多态的概述以及使用"></a>一、多态的概述以及使用</h2><p>啥叫多态？左父右子，就叫多态。此处联想css中的子绝父相。</p>
<img src="/2019/09/23/polymorphism/多态1.png" title="多态的概述">

<p>代码当中提现多态性，其实就是一句话：父类引用指向子类对象</p>
<p>格式：</p>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">父类对象 对象名 = <span class="keyword">new</span> <span class="type"></span>子类名称();</span><br></pre></td></tr></table></figure>

<p>或者</p>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">接口名称 对象名 = <span class="keyword">new</span> <span class="type"></span>实现类名称();</span><br></pre></td></tr></table></figure>

<p>Fu.java</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">Fu</span> &#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">method</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">		System.<span class="keyword">out</span>.println(<span class="string">"父类方法"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">methodFu</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">		System.<span class="keyword">out</span>.println(<span class="string">"这是父类特有的方法"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Zi.java</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">public <span class="class"><span class="keyword">class</span> <span class="title">Zi</span> <span class="keyword">extends</span> <span class="title">Fu</span> </span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	public void method() &#123;</span><br><span class="line">		<span class="type">System</span>.out.println(<span class="string">"子类方法"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Demo01Multi.java</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo01Multi</span> &#123;</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		</span><br><span class="line">		<span class="comment">//使用多态方法</span></span><br><span class="line">		<span class="comment">//左侧父类的引用，指向右侧子类的对象</span></span><br><span class="line">		Fu obj=<span class="keyword">new</span> Zi();</span><br><span class="line">		</span><br><span class="line">		obj.method();<span class="comment">//子类方法。看右边new的是谁，就输出谁</span></span><br><span class="line">		obj.methodFu();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="二、多态中成员变量使用特点"><a href="#二、多态中成员变量使用特点" class="headerlink" title="二、多态中成员变量使用特点"></a>二、多态中成员变量使用特点</h2><p>访问成员变量的两种方式：</p>
<ol>
<li>直接通过对象名称访问成员变量：看等号左边是谁，优先用谁，没有则向上找</li>
<li>间接通过成员方法访问成员变量：看该方法属于谁，优先用谁，没有则向上找</li>
</ol>
<p>Fu1.java</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">Fu1</span> &#123;</span><br><span class="line">	<span class="keyword">int</span> num=<span class="number">10</span>;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">method</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">		System.<span class="keyword">out</span>.println(<span class="string">"父类"</span>+num);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Zi1.java</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">public <span class="class"><span class="keyword">class</span> <span class="title">Zi1</span> <span class="keyword">extends</span> <span class="title">Fu1</span> </span>&#123;</span><br><span class="line">	int num=<span class="number">20</span>;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	public void method() &#123;</span><br><span class="line">		<span class="type">System</span>.out.println(<span class="string">"子类"</span>+num);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Demo02MultiField.java</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">Demo02MultiField</span> &#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span>(<span class="params">String[] args</span>)</span> &#123;</span><br><span class="line">		<span class="comment">//使用多态的方法，父类引用指向子类对象，左父右子</span></span><br><span class="line">		Fu1 obj=<span class="keyword">new</span> Zi1();</span><br><span class="line">		System.<span class="keyword">out</span>.println(obj.num);<span class="comment">//10</span></span><br><span class="line">		obj.method();<span class="comment">//20,子类没有覆盖重写，就是父；子类如果覆盖重写，就是子</span></span><br><span class="line">		</span><br><span class="line">		Zi1 zi=<span class="keyword">new</span> Zi1();</span><br><span class="line">		System.<span class="keyword">out</span>.println(zi.num);<span class="comment">//20</span></span><br><span class="line">		zi.method();<span class="comment">//20</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="三、多态中成员方法的使用特点"><a href="#三、多态中成员方法的使用特点" class="headerlink" title="三、多态中成员方法的使用特点"></a>三、多态中成员方法的使用特点</h2><p>在多态的代码当中，成员方法的访问规则：</p>
<p><em>看new的是谁，就优先用谁，没有则向上找</em></p>
<p>口诀：编译看左边，运行看右边</p>
<p><strong>对比：</strong></p>
<p>成员变量：编译看左边，运行还看左边</p>
<p>成员方法：编译看左边，运行看右边</p>
<p>Fu2.java</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">Fu2</span> &#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">method</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">		System.<span class="keyword">out</span>.println(<span class="string">"父类方法"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">methodFu</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">		System.<span class="keyword">out</span>.println(<span class="string">"父类特有的方法"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Zi2.java</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">public <span class="class"><span class="keyword">class</span> <span class="title">Zi2</span> <span class="keyword">extends</span> <span class="title">Fu2</span> </span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	public void method() &#123;</span><br><span class="line">		<span class="type">System</span>.out.println(<span class="string">"子类方法"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public void methodZi() &#123;</span><br><span class="line">		<span class="type">System</span>.out.println(<span class="string">"子类特有方法"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Demo03MultiMethod.java</p>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo03MultiMethod</span> </span>&#123;</span><br><span class="line">	<span class="keyword">public</span> <span class="keyword">static</span> void main(<span class="keyword">String</span>[] args) &#123;</span><br><span class="line">		Fu2 obj=<span class="keyword">new</span> <span class="type">Zi2</span>();<span class="comment">//多态</span></span><br><span class="line">		obj.method();<span class="comment">//父子都有，优先用子</span></span><br><span class="line">		obj.methodFu();<span class="comment">//子类没有，父类有，向上找</span></span><br><span class="line">		</span><br><span class="line">		<span class="comment">//obj.methodZi();//报错了,因为编译看左边，左边是Fu,Fu当中没有methodZi方法，所以编译报错</span></span><br><span class="line">		</span><br><span class="line">		Zi2 zi=<span class="keyword">new</span> <span class="type">Zi2</span>();</span><br><span class="line">		zi.methodZi();</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="四、使用多态的好处"><a href="#四、使用多态的好处" class="headerlink" title="四、使用多态的好处"></a>四、使用多态的好处</h2><img src="/2019/09/23/polymorphism/多态2.png" title="使用多态的好处">

<p>如果不用多态，只用子类，那么写法是：</p>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Teacher one = <span class="keyword">new</span> <span class="type">Teacher</span>();</span><br><span class="line">one.work();<span class="comment">//讲课</span></span><br><span class="line">Assistant two = <span class="keyword">new</span> <span class="type">Assistant</span>();</span><br><span class="line">two.work();<span class="comment">//辅导</span></span><br></pre></td></tr></table></figure>

<p>我现在唯一要做的事情，就是调用work方法，其他的功能不关心。</p>
<p>如果使用多态的写法，对比一下：</p>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Employee one = <span class="keyword">new</span> <span class="type">Teacher</span>();</span><br><span class="line">one.work();<span class="comment">//讲课</span></span><br><span class="line">Employee two = <span class="keyword">new</span> <span class="type">Assistant</span>();</span><br><span class="line">two.work();<span class="comment">//辅导</span></span><br></pre></td></tr></table></figure>

<p><strong>好处：</strong></p>
<p><em>无论右边new的时候换成哪个子类对象，等号左边调用方法不会发生变化</em></p>
<h2 id="五、对象的向上转型与向下转型"><a href="#五、对象的向上转型与向下转型" class="headerlink" title="五、对象的向上转型与向下转型"></a>五、对象的向上转型与向下转型</h2><img src="/2019/09/23/polymorphism/多态3.png" title="上转型与下转型理解图">

<h4 id="向上转型"><a href="#向上转型" class="headerlink" title="向上转型"></a>向上转型</h4><p>对象的向上转型，其实就是多态写法：</p>
<figure class="highlight haxe"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">父类名称 对象名 = <span class="keyword">new</span> <span class="type"></span>子类名称();</span><br><span class="line"></span><br><span class="line"><span class="comment">//Animal animal = new Cat();</span></span><br><span class="line"><span class="comment">//创建了一只猫，当做动物看待，没问题。</span></span><br></pre></td></tr></table></figure>

<p>含义：右侧创建一个子类对象，把它当做父类来看待使用。</p>
<p>注意事项：<strong>向上转型一定是安全的。</strong>从小范围转向了大范围，从小范围的猫，转向了更大范围的动物。</p>
<p>类似于：</p>
<figure class="highlight coq"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">double</span> num=<span class="number">100</span>;//正确，int--&gt;<span class="built_in">double</span>,自动类型转换</span><br></pre></td></tr></table></figure>

<h4 id="向下转型"><a href="#向下转型" class="headerlink" title="向下转型"></a>向下转型</h4><p>对象的向下转型，其实是一个【还原】的动作</p>
<p>格式：</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">子类名称 对象名 = (子类名称) 父类对象;<span class="regexp">//</span>其实类似于 int a = (double) <span class="number">10.0</span>;</span><br><span class="line"></span><br><span class="line"><span class="regexp">//</span>Animal animal = new Cat();<span class="regexp">//</span>本来是猫，向上转型为动物</span><br><span class="line"><span class="regexp">//</span>Cat cat = (Cat) animal;<span class="regexp">//</span>本来是猫，已经被当做动物了，还原为本来的猫</span><br></pre></td></tr></table></figure>

<p>含义：将父类对象，【还原】成为本来的子类对象。</p>
<p>注意事项：</p>
<ol>
<li>必须保证对象本来创建的时候，就是猫，才能向下转型成为猫</li>
<li>如果对象创建的时候本来不是猫，现在非要向下转型为猫，就会报错。<strong>java.lang.ClassCastException</strong></li>
</ol>
<p>类似于：</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">int</span> <span class="built_in">num</span> = (<span class="built_in">int</span>) <span class="number">10.0</span>;<span class="comment">//可以</span></span><br><span class="line"><span class="built_in">int</span> <span class="built_in">num</span> = (<span class="built_in">int</span>) <span class="number">10.5</span>;<span class="comment">//不可以，精度损失</span></span><br></pre></td></tr></table></figure>

<p>Animal.java</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title">Animal</span> &#123;</span><br><span class="line">	</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">eat</span>(<span class="params"></span>)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Cat.java</p>
<figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">public <span class="class"><span class="keyword">class</span> <span class="title">Cat</span> <span class="keyword">extends</span> <span class="title">Animal</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	public void eat() &#123;</span><br><span class="line">		<span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line">		<span class="type">System</span>.out.println(<span class="string">"猫吃鱼"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">	public void catchMouse() &#123;</span><br><span class="line">		<span class="type">System</span>.out.println(<span class="string">"猫抓老鼠"</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Demo04Main.java</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">向上转型一定是安全的，没有问题的，正确的，但是也有一个弊端：</span></span><br><span class="line"><span class="comment">对象一旦向上转型为父类，那么就无法调用子类原本特有的内容。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">解决方案：用对象的向下转型【还原】</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo04Main</span> &#123;</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		<span class="comment">// 对象的向上转型，就是：父类引用指向子类对象</span></span><br><span class="line">		Animal animal = <span class="keyword">new</span> Cat();<span class="comment">//本来是一只猫，向上转型为动物；向上转型必定是成功的。</span></span><br><span class="line">		animal.eat();</span><br><span class="line">		<span class="comment">// animal.catchMouse();//错误写法!要改成向下转型</span></span><br><span class="line"></span><br><span class="line">		</span><br><span class="line">		<span class="comment">//向下转型，正确的转型，本来是只猫，还转换成猫，所以是正确的</span></span><br><span class="line">		Cat cat = (Cat) animal;<span class="comment">//类似于强制转换</span></span><br><span class="line">		cat.catchMouse();<span class="comment">//猫抓老鼠</span></span><br><span class="line">		</span><br><span class="line">		<span class="comment">//下面是错误的转型</span></span><br><span class="line">		<span class="comment">//本来是只猫，现在当做狗</span></span><br><span class="line">		<span class="comment">//Dog dog=(Dog) animal;//编译时没错，运行会出现异常。java.lang.ClassCastException  </span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="六、instanceof判断类型"><a href="#六、instanceof判断类型" class="headerlink" title="六、instanceof判断类型"></a>六、instanceof判断类型</h2><p>如何才能知道一个父类引用的对象，本来是什么子类？</p>
<p>格式：</p>
<figure class="highlight actionscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">对象 <span class="keyword">instanceof</span> 类名称</span><br></pre></td></tr></table></figure>

<p>这将会得到一个boolean值结果，也就是判断前面的对象能不能做后面类型的实例</p>
<p><em>向下转型，一定要进行instanceof判断，否则，可能会出现转换异常</em></p>
<p>Animal.java跟Cat.java跟上面那个是一个类，直接看Instanceof类</p>
<p>Demo02Instanceof.java</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Demo02Instanceof</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		Animal animal = <span class="keyword">new</span> Cat();</span><br><span class="line">		animal.eat();<span class="comment">// 猫吃鱼</span></span><br><span class="line">		giveMeAPat(animal);</span><br><span class="line"></span><br><span class="line">		</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">giveMeAPat</span><span class="params">(Animal animal)</span> </span>&#123;</span><br><span class="line">		<span class="comment">// 如果希望调用子类特有方法，需要向下转型</span></span><br><span class="line">		<span class="keyword">if</span> (animal <span class="keyword">instanceof</span> Dog) &#123;</span><br><span class="line">			Dog dog = (Dog) animal;</span><br><span class="line">			dog.watchHouse();</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">if</span> (animal <span class="keyword">instanceof</span> Cat) &#123;</span><br><span class="line">			Cat cat = (Cat) animal;</span><br><span class="line">			cat.catchMouse();</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="七、接口多态综合案例"><a href="#七、接口多态综合案例" class="headerlink" title="七、接口多态综合案例"></a>七、接口多态综合案例</h2><img src="/2019/09/23/polymorphism/多态4.png" title="案例要求">

<p>USB.java</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title">USB</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">open</span>(<span class="params"></span>)</span>; <span class="comment">// 打开设备</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title">close</span>(<span class="params"></span>)</span>; <span class="comment">// 关闭设备</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Mouse.java</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//鼠标就是一个USB设备</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Mouse</span> <span class="keyword">implements</span> <span class="title">USB</span> </span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">open</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"打开鼠标"</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">close</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"关闭鼠标"</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">click</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"鼠标点击"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Keyboard.java</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//键盘就是一个USB设备</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Keyboard</span> <span class="keyword">implements</span> <span class="title">USB</span> </span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">open</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"打开键盘"</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">close</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"关闭键盘"</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">type</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">"键盘输入"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Computer.java</p>
<figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> class Computer &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> powerOn() &#123;</span><br><span class="line">        System.out.<span class="built_in">println</span>(<span class="string">"笔记本电脑开机"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> powerOff() &#123;</span><br><span class="line">        System.out.<span class="built_in">println</span>(<span class="string">"笔记本电脑关机"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 使用USB设备的方法，使用接口作为方法的参数</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> useDevice(USB usb) &#123;</span><br><span class="line">        usb.<span class="built_in">open</span>(); <span class="comment">// 打开设备</span></span><br><span class="line">        <span class="built_in">if</span> (usb instanceof <span class="built_in">Mouse</span>) &#123; <span class="comment">// 一定要先判断</span></span><br><span class="line">            <span class="built_in">Mouse</span> mouse = (<span class="built_in">Mouse</span>) usb; <span class="comment">// 向下转型</span></span><br><span class="line">            mouse.<span class="built_in">click</span>();</span><br><span class="line">        &#125; <span class="built_in">else</span> <span class="built_in">if</span> (usb instanceof <span class="built_in">Keyboard</span>) &#123; <span class="comment">// 先判断</span></span><br><span class="line">            <span class="built_in">Keyboard</span> keyboard = (<span class="built_in">Keyboard</span>) usb; <span class="comment">// 向下转型</span></span><br><span class="line">            keyboard.type();</span><br><span class="line">        &#125;</span><br><span class="line">        usb.<span class="built_in">close</span>(); <span class="comment">// 关闭设备</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>DemoMain.java</p>
<figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> class DemoMain &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> main(<span class="keyword">String</span>[] args) &#123;</span><br><span class="line">        <span class="comment">// 首先创建一个笔记本电脑</span></span><br><span class="line">        Computer computer = <span class="keyword">new</span> Computer();</span><br><span class="line">        computer.powerOn();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 准备一个鼠标，供电脑使用</span></span><br><span class="line"><span class="comment">//        Mouse mouse = new Mouse();</span></span><br><span class="line">        <span class="comment">// 首先进行向上转型</span></span><br><span class="line">        USB usbMouse = <span class="keyword">new</span> <span class="built_in">Mouse</span>(); <span class="comment">// 多态写法</span></span><br><span class="line">        <span class="comment">// 参数是USB类型，我正好传递进去的就是USB鼠标</span></span><br><span class="line">        computer.useDevice(usbMouse);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建一个USB键盘</span></span><br><span class="line">        <span class="built_in">Keyboard</span> keyboard = <span class="keyword">new</span> <span class="built_in">Keyboard</span>(); <span class="comment">// 没有使用多态写法</span></span><br><span class="line">        <span class="comment">// 方法参数是USB类型，传递进去的是实现类对象</span></span><br><span class="line">        computer.useDevice(keyboard); <span class="comment">// 正确写法！也发生了向上转型</span></span><br><span class="line">        <span class="comment">// 使用子类对象，匿名对象，也可以</span></span><br><span class="line"><span class="comment">//        computer.useDevice(new Keyboard()); // 也是正确写法</span></span><br><span class="line"></span><br><span class="line">        computer.powerOff();</span><br><span class="line">        System.out.<span class="built_in">println</span>(<span class="string">"=================="</span>);</span><br><span class="line"></span><br><span class="line">        method(<span class="number">10.0</span>); <span class="comment">// 正确写法，double --&gt; double</span></span><br><span class="line">        method(<span class="number">20</span>); <span class="comment">// 正确写法，int --&gt; double</span></span><br><span class="line">        <span class="keyword">int</span> a = <span class="number">30</span>;</span><br><span class="line">        method(a); <span class="comment">// 正确写法，int --&gt; double</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> method(<span class="keyword">double</span> num) &#123;</span><br><span class="line">        System.out.<span class="built_in">println</span>(num);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="八、多态的练习题"><a href="#八、多态的练习题" class="headerlink" title="八、多态的练习题"></a>八、多态的练习题</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> homework;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">f</span><span class="params">(D obj)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> (<span class="string">"A and D"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">f</span><span class="params">(A obj)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> (<span class="string">"A and A"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">f</span><span class="params">(B obj)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> (<span class="string">"B and B"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">f</span><span class="params">(A obj)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> (<span class="string">"B and A"</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">C</span> <span class="keyword">extends</span> <span class="title">B</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">D</span> <span class="keyword">extends</span> <span class="title">B</span> </span>&#123;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Homework02</span> </span>&#123;</span><br><span class="line">	<span class="comment">/*</span></span><br><span class="line"><span class="comment">	 * 这个地方需要注意的点：</span></span><br><span class="line"><span class="comment">	 * 1. 如果public String f(A obj)方法传进来的对象是B对象，发现没有，就会自动向上转型！因为B extends A</span></span><br><span class="line"><span class="comment">	 * 2. 向上转型的写法中：A a2=new B();a2调用变量是A中的，调用方法是B中的(只能是A中已有的方法，被重写的可以被调用，独有的是不可以被调用的)</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		A a1=<span class="keyword">new</span> A();</span><br><span class="line">		A a2=<span class="keyword">new</span> B();</span><br><span class="line">		B b=<span class="keyword">new</span> B();</span><br><span class="line">		C c=<span class="keyword">new</span> C();</span><br><span class="line">		D d=<span class="keyword">new</span> D();</span><br><span class="line">		</span><br><span class="line">		System.out.println(a1.f(a1));<span class="comment">// A and A</span></span><br><span class="line">		System.out.println(a1.f(b));<span class="comment">// A and A</span></span><br><span class="line">		System.out.println(a1.f(c));<span class="comment">// A and A</span></span><br><span class="line">		System.out.println(a1.f(d));<span class="comment">// A and D</span></span><br><span class="line">		</span><br><span class="line">		System.out.println(a2.f(a1));<span class="comment">//B and A</span></span><br><span class="line">		System.out.println(a2.f(b)); <span class="comment">//B and A</span></span><br><span class="line">		System.out.println(a2.f(c));<span class="comment">//B and A</span></span><br><span class="line">		System.out.println(a2.f(d));<span class="comment">//A and D</span></span><br><span class="line">		</span><br><span class="line">		System.out.println(b.f(a1));<span class="comment">//B and A</span></span><br><span class="line">		System.out.println(b.f(b));<span class="comment">//B and B</span></span><br><span class="line">		System.out.println(b.f(c));<span class="comment">//B and B</span></span><br><span class="line">		System.out.println(b.f(d));<span class="comment">//A and D</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
        </div>
        
            <div class="busuanzi">
                <span id="busuanzi_container_page_pv">阅读量<span id="busuanzi_value_page_pv"></span>次</span>
                <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            </div>
        
    </article>
</div>
    <pointer href="javascript:void(0);" class="arrow fa fa-arrow-up"></pointer>
<pointer href="javascript:void(0);" class="arrow fa fa-arrow-down"></pointer>

</main>
<aside class="aside">
    <div class="aside-content">
        <div class="aside-avatar"><img src="/images/kitchen.jpg" alt="言成"></div>
        <div class="aside-author">言成</div>
        <div class="aside-description">爱学习，爱运动，爱看妹子</div>
        <ul class="aside-contact clearFix">
            <li><span class="fa fa-github"></span><a href="https://github.com/meethigher">Github</a></li>
            <li><span class="fa fa-envelope"></span><a href="javascript:void(0);">meethigher@qq.com</a></li>
            <li><span class="fa fa-weixin"></span><a href="javascript:void(0);"><img src="/images/weixin.png" alt="扫描微信二维码，加我哦！"></a></li>
        </ul>
    </div>
</aside>
<div class="toolbar"><span class="fa fa-th"></span></div>
<div id="particles-js"></div>
<script src="https://cdn.jsdelivr.net/gh/meethigher/cdn@9.0/js/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/meethigher/cdn@9.0/js/particles.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/meethigher/cdn@9.0/js/app.js"></script>
<script src="/js/meethigher.js"></script>
<script src="/js/toolbar.js"></script>
</body>
</html>